package com.silence.springboot.service.impl;


import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.silence.springboot.constants.StringConstants;
import com.silence.springboot.convert.LoginConvert;
import com.silence.springboot.dao.LoginDao;
import com.silence.springboot.dao.UserBaseInfoDao;
import com.silence.springboot.entity.LoginEntity;
import com.silence.springboot.entity.UserBaseInfoEntity;
import com.silence.springboot.enums.ResultCode;
import com.silence.springboot.exception.ApiException;
import com.silence.springboot.mapper.LoginMapper;
import com.silence.springboot.properties.JwtProperties;
import com.silence.springboot.service.LoginService;
import com.silence.springboot.utils.JwtUtil;
import com.silence.springboot.vo.input.LoginSystemInput;
import com.silence.springboot.vo.input.RegisterUserInput;
import com.silence.springboot.vo.input.UpdatePasswordInput;
import com.silence.springboot.vo.output.LoginSystemOutput;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

/**
 * 管理员登录表 服务层实现。
 *
 * @author mybatis-flex-helper automatic generation
 * @since 1.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class LoginServiceImpl extends ServiceImpl<LoginMapper, LoginEntity> implements LoginService {

    /**
     * 登录表 转换类
     */
    private final LoginConvert loginConvert;

    /**
     * JWT配置类
     */
    private final JwtProperties jwtProperties;

    /**
     * 登录表 数据访问层实现
     */
    private final LoginDao loginDao;

    /**
     * 用户基础信息表 数据访问层接口
     */
    private final UserBaseInfoDao userBaseInfoDao;

    /**
     * 注册用户
     *
     * @param input 注册用户入参
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void registerUser(RegisterUserInput input) {
        // 获取用户名和密码和身份
        String username = input.getUsername();
        String password = input.getPassword();
        String standing = input.getStanding();
        // 查询登录表数量
        long count = loginDao.selectCountByUserName(username);
        if (count > 0) {
            throw new ApiException(ResultCode.LOGIN_USER_USERNAME_EXIST);
        }
        // 插入表
        save(new LoginEntity().setUsername(username).setPassword(password));
        // 查询数据库中的用户
        LoginEntity selectEntity = loginDao.selectOneByQuery(username);
        // 获取ID
        long loginId = selectEntity.getId();
        String token = JwtUtil.createToken(System.currentTimeMillis(), selectEntity.getId());
        log.info("生成的 Token 为：{}", token);
        // 插入 user_base_info 表
        userBaseInfoDao.insertOrUpdate(new UserBaseInfoEntity()
                .setLoginId(loginId)
                .setToken(jwtProperties.getTokenHeader().concat(token))
                .setLoginFlag(standing));
    }

    /**
     * 登录系统
     *
     * @param input 登录表入参
     * @return 登录表出参
     */
    @Override
    public LoginSystemOutput loginAdminSystem(LoginSystemInput input) {
        // 转换实体类
        LoginEntity entity = loginConvert.loginSystemInputToLoginAdminEntity(input);
        // 获取用户名和密码
        String username = entity.getUsername();
        String password = entity.getPassword();
        log.info("用户名：{}，密码：{}", username, password);
        // 查询数据库中的用户名和密码
        LoginEntity selectEntity = loginDao.selectOneByQuery(username);
        // 判断用户名和密码是否正确
        if (Objects.isNull(selectEntity)) {
            throw new ApiException(ResultCode.LOGIN_USER_NOT_FOUND);
        }
        // 判断密码是否正确
        if (!Objects.equals(input.getPassword(), selectEntity.getPassword())) {
            throw new ApiException(ResultCode.LOGIN_USER_PASSWORD_ERROR);
        }
        // 获取登录标识
        String loginFlag = input.getStanding();
        long loginId = selectEntity.getId();
        long count = userBaseInfoDao.queryCountByLoginIdAndLoginFlag(loginId, loginFlag);
        if (count == 0) {
            throw new ApiException(ResultCode.LOGIN_USER_NOT_FOUND);
        }
        log.info("登录成功");
        String token = JwtUtil.createToken(System.currentTimeMillis(), selectEntity.getId());
        log.info("生成的 token 为：{}", token);
        userBaseInfoDao.updateTokenByUserId(selectEntity.getId(), jwtProperties.getTokenHeader().concat(token));
        // 构建出参
        return new LoginSystemOutput()
                .setAuthHeader(jwtProperties.getAuthHeader())
                .setExpiration(jwtProperties.getExpiration())
                .setTokenHeader(jwtProperties.getTokenHeader())
                .setToken(token);
    }

    /**
     * 修改密码
     *
     * @param input 修改密码入参
     */
    @Override
    public void updatePassword(UpdatePasswordInput input) {
        String oldPassword = input.getOldPassword();
        String newPassword = input.getNewPassword();
        String confirmPassword = input.getConfirmPassword();
        String token = StringConstants.AUTHORIZATION_HEADER.concat(input.getToken());
        // 判断新旧密码是否相同
        if (!Objects.equals(newPassword, confirmPassword)) {
            throw new ApiException(ResultCode.LOGIN_USER_PASSWORD_NOT_SAME);
        }
        LoginEntity loginEntity = userBaseInfoDao.selectUserLoginInfoByToken(token);
        if (Objects.isNull(loginEntity)) {
            throw new ApiException(ResultCode.LOGIN_USER_NOT_FOUND);
        }
        Long selectId = loginEntity.getId();
        String selectPassword = loginEntity.getPassword();
        if (!Objects.equals(selectPassword, oldPassword)) {
            throw new ApiException(ResultCode.LOGIN_USER_PASSWORD_ERROR);
        }
        LoginEntity updateEntity = new LoginEntity();
        updateEntity.setId(selectId);
        updateEntity.setPassword(newPassword);
        updateById(updateEntity);
    }
}